package br.senac.arqpad.pizzaria.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import br.senac.arqpad.pizzaria.model.ClasseComId;
import br.senac.arqpad.pizzaria.model.Repository;

public class DAOJPA<T extends ClasseComId> implements Repository<T>  {

	private Class<T> tipoItem;
		
	public DAOJPA(Class<T> tipoItem) {
		super();
		this.tipoItem = tipoItem;
	}

	@Override
	public List<T> getLista() {
		return listarTodos();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> listarTodos() {
	
		try			
		{
			
			List<T> lista = null;
			String sql = "from " + tipoItem.getCanonicalName();
			EntityManager gerente = obterEntityManager();
			lista = (List<T>) gerente.createQuery(sql).getResultList();
			gerente.close();
			return lista;
	
		}
		catch(Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	@Override
	public boolean incluir(T item) {
				
		try {
		
			EntityManager gerente = obterEntityManager();

			gerente.getTransaction().begin();
			gerente.persist(item);
			gerente.getTransaction().commit();

			gerente.close();
						
			return true;
		
		}			
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private EntityManager obterEntityManager() {
		
		EntityManagerFactory fabrica = Persistence
				.createEntityManagerFactory("pizzaria");
		
		EntityManager gerente = fabrica.createEntityManager();
		
		return gerente;
	}
	
	@Override
	public boolean atualizar(T item) {
		
		
		try {
	
			EntityManager gerente = obterEntityManager();

			gerente.getTransaction().begin();
			gerente.merge(item);
			gerente.getTransaction().commit();

			gerente.close();
			
			return true;
		
		}			
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}


	@Override
	public boolean excluir(ClasseComId itemProcurado) {
				
		try {
	
			EntityManager gerente = obterEntityManager();

			T itemAExcluir = gerente.find(tipoItem,itemProcurado.getId());
			gerente.getTransaction().begin();
			gerente.remove(itemAExcluir);
			gerente.getTransaction().commit();

			gerente.close();
			return true;
		
		}			
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T obter(ClasseComId itemProcurado) {
	
		try			
		{
			
			T item=null;
			EntityManager gerente = obterEntityManager();
			item = (T) gerente.find(tipoItem,itemProcurado.getId());
			gerente.close();
	
			// Retorna o objeto
			return item;		
		}
		catch(Exception e) {
			throw new RuntimeException(e.getMessage());
		}	
	}
	
}